//1 trait 用于定义与其他类型共享的功能，类似与其他语言的接口

/// 可以通过trait 以抽象的方式定义共享的行为
/// 可以使用trait bounds 指定范型是任何拥有特定行为的类型
/// 
// 2 定义trait 
pub trait GetInformation{
    fn get_name(&self)->String;
    fn get_age(&self)->u32;
}
trait SchoolName{
    fn get_school_name(&self)->String{
        String::from("Hongxing School")
    }
}

//3 实现trait
//定义学生
pub struct Student{
    pub name:String,
    pub age:u32
}
impl GetInformation for Student{
    fn get_name(&self)->String{
       format!("{}", self.name)
    }
    fn get_age(&self)->u32{
        self.age
    }
}
impl SchoolName for Student{}

// 老师类
pub struct Teacher{
    pub name:String,
    pub age:u32,
    pub subject:String
}

impl GetInformation for Teacher{
    fn get_name(&self)->String{
        format!("{}", self.name)
    }
    fn get_age(&self)->u32{
        self.age
    }
}
impl SchoolName for Teacher{}

//4 默认实现，可以在定义trait 的时候提供默认的行为，trait 的类型可以使用默认行为

//5 trait 作为参数
fn print_information(item:impl GetInformation){
    println!("这里是trait作为参数：{} \n ",item.get_name())
}

fn main() {

    let student=Student{
        name:String::from("Jhon"),
        age:23
    };
    println!("学生 name:{},\n age:{} \n\n\n",student.get_name(),student.get_age());
    print_information(student);
    let teacher=Teacher{
        name:String::from("王老师"),
        age:33,
        subject:String::from("shuxue"),
    };

      let sch_name=  teacher.get_school_name();
      println!("School name:{}",sch_name);
    println!("老师 name:{},\n age:{},\n subject:{}",teacher.get_name(),teacher.get_age(),teacher.subject);

    
}
